#include <stdio.h>
//void print(int (*p) [5],int row,int col)
//{
//    int i = 0;
//    for(i = 0;i < row;i++)
//    {
//        int j = 0;
//        for(j = 0;j < col;j++)
//        {
////          printf("%d ",(*p)[j]);
////          printf("%d ",*(*p+j));//始终想不出一种办法保留(*p)+i的形式。
////          printf("%d ",*(*(p+i)+j));
//            printf("%d ",(*(p+i))[j]);
//        }
//        printf("\n");
//    }
//}
//int main() {
//    int arr[3][5] = {1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};
//    print(arr,3,5);
//    return 0;
//}

//void print(int n)
//{
//    if(n > 0)
//    {
//        printf("%d",n%10);
//        print(n/10);
//    }
//}
//int main() {
//    int n = 0;
//    scanf("%d",&n);
//    print(n);
//    return 0;
//}

//int h_y(int n,int x)
//{
//    if(n == 0)
//        return 1;
//    else if(n == 1)
//        return 2*n;
//    else
//    {
//        return (2*x*h_y(n-1,x))-(2*(n-1)*h_y(n-2,x));
//    }
//}
//int main() {
//    int n = 0;
//    int x = 0;
//    scanf("%d %d",&n,&x);
//    printf("%d\n",h_y(n,x));
//    return 0;
//}

#include <math.h>
//void digit(int x,int i)
//{
//    if(i >= 0)
//    {
//        printf("%d",(x/(int)pow(10,i-1))%10);
//        digit(x,--i);
//    }
//}
//int main() {
//    int x = 0;
//    int i = 0;
//    scanf("%d %d",&x,&i);
//    digit(x,i);
////    int x = 23908;
////    int g = (x/100) %10;
////    printf("%d\n",g);
//    return 0;
//}

//int Ackmann(int n,int m)
//{
//    if(m == 0)
//        return n+1;
//    else if(m > 0 && n == 0)
//        return Ackmann(m-1,1);
//    else
//        return Ackmann(m-1,Ackmann(m,n-1));
//}
//int main() {
//    int n = 0;
//    int m = 0;
//    scanf("%d %d",&n,&m);
//    printf("%d\n",Ackmann(n,m));
//    return 0;
//}

//int main() {
//    int n = 0;
//    scanf("%d",&n);
//    int arr[n];
//    int i = 0;
//    for(i = 0;i < n;i++)
//    {
//        scanf("%d",&arr[i]);
//    }
//    for(i = 0;i < n;i++)
//    {
//        if(arr[i] == 2)
//            printf("true\n");
//        else
//        {
//            int j = 1;
//            int count = 0;
//            for(j = 2;j < arr[i];j++)
//            {
//                if(arr[i] % j != 0)
//                    count++;
//                else
//                {
//                    printf("false\n");
//                    break;
//                }
//
//            }
//            if(count == (arr[i] - 2))
//                printf("true\n");
//        }
//    }
//    return 0;
//}

//int main() {
//    int n = 0;
//    scanf("%d",&n);
//    int arr[n];
//    int i = 0;
//    int count = 0;
//    for(i = 0;i < n;i++)
//    {
//        scanf("%d",&arr[i]);
//        int j = (arr[i])%10;
//        //根是整数，这怎么弄？
//        if((j == 0||j == 1||j == 4||j == 5||j == 6||j == 9) && (((sqrt(arr[i]))-floor(sqrt(arr[i]))) == 0))
//            count++;
//    }
//    int arr_1[n-count];//创建新数组，不包含完全平方数
//    int x = 0;
//    for(i = 0;i < n;i++)
//    {
//        int j = (arr[i])%10;
//        if((j == 0||j == 1||j == 4||j == 5||j == 6||j == 9) && (((sqrt(arr[i]))-floor(sqrt(arr[i]))) == 0))
//            ;
//        else
//        {
//            arr_1[x++] = arr[i];//不是就赋给它，然后++；
//        }
//    }
//    int max = arr_1[0];
//    for(i = 1;i < n-count;i++)
//    {
//        if(arr[i] > max)
//            max = arr[i];
//    }
//    printf("%d\n",max);
//    return 0;
//}

//int main() {
//    int n = 0;
//    char a = 0;
//    char b = 0;
//    char c = 0;
//    char d = 0;
//    scanf("%d %c %c %c %c",&n,&a,&b,&c,&d);
//    getchar();
//    char arr[n];
//    int i = 0;
//    for(i = 0;i < n;i++)
//    {
//        scanf("%c",&arr[i]);
//        if(arr[i] == a)
//        {
//            arr[i] = b;
//            if(arr[i] == c)
//                arr[i] = d;
//        }
//        else if(arr[i] == c)
//            arr[i] = d;
//    }
//    for(i = 0;i < n;i++)
//    {
//        printf("%c",arr[i]);
//    }
//    return 0;
//}


////自检：写一个函数，判断一个数是几位数
//int Strip(int a,int i)//成功得到个数之和
//{
//    if(i == 1)
//        return a;
//    else
//       return a%10 + Strip(a/10,i-1);
//}
//int main()
//{
//    int a = 0;
//    scanf("%d",&a);
//    int i = 0;
////0~9/10^1 = 0;
////10~99/10^2 = 0;
////100~999/10^3 = 0；
////......
//    for(i = 1;i < a;i++)
//    {
//        if(a/pow(10,i) < 1)
//            break;
//    }
//    printf("%d\n",i);
//    printf("%d\n",Strip(a,i));
//    return 0;
//}

//int Strip(int a,int i)//成功得到个数之和
//{
//    if(i == 1)
//        return a;
//    else
//        return a%10 + Strip(a/10,i-1);
//}
//int main()
//{
//    int a = 0;
//    int b = 0;
//    scanf("%d %d",&a,&b);
//    int i = 0;
//    int j = 0;
//    int count = 0;
//    for(j = a;j < b;j++)
//    {
//        for(i = 1;i < j;i++)//这是假定一个最大的次方数是j，实际上不可能次方数达到j。
//        {
//            if(j/pow(10,i) < 1)
//                break;
//        }
//        int ret =  Strip(j,i);
//        if(ret % 5 == 0)
//            count++;
//    }
//    printf("%d\n",count);
//    return 0;
//}


//int Judg(int i)
//{
//    int j = 0;
//    for(j = 1;j < i;j++)
//    {
//        if(i/pow(10,j) < 1)
//            break;
//    }
//    return j;
//}
//int Strip(int i,int j)//返回几个2
//{
//    if(j == 1 && i == 2)
//        return 1;
//    else if(j == 1 && i != 2)
//        return 0;
//    else
//    {
//        if(i%10 == 2)
//        {
////            count+=1;
//            return 1+ Strip(i/10,j-1);
//        }
//        //当%10,剩下的数不是2时，直接递归。
//        else
//            return Strip(i/10,j-1);
//    }
//}
//int main() {
//    int L = 0;
//    int R = 0;
//    scanf("%d %d",&L,&R);
//    int i = 0;
//    int count = 0;
//    for(i = L;i <= R;i++)
//    {
//        //判断是几位数
//        int judg = Judg(i);
//        //根据是几位数进行剥数
//        count += Strip(i,judg);
//    }
////    int a = 32837822;//出问题了
////    int judg = Judg(a);
////    int count = 0;
////    int ret = Strip(a,judg);
//    printf("%d\n",count);
//    return 0;
//}







////牛客网这一道题有毛病，二进制的”1“中数字“1”的个数很明显只有1个啊，那数字”0“就有32-1=31个啊，它说”0“的个数是偶数个
////BC165——牛牛的10类人
////顺便一说：题目表达的意思都有问题，可能免费练习的是这样的。
////判断二进制序列中有多少个1
//int Ju_bi(int a)
//{
//    int i = 0;
//    int count = 0;
//    for(i = 0;i < 32;i++)//是要待比较的数移动，移动31位就到32位上了，然后按位与。
//    {
//        if(((a>>i) & 1) == 1)
//            count++;
//    }
//    return count;
//}
//int main() {
//    int n = 0;
//    scanf("%d",&n);
//    int arr[n];
//    int i = 0;
//    for(i = 0;i < n;i++)
//    {
//        scanf("%d",&arr[i]);
//        int ret = Ju_bi(arr[i]);
//        if((ret%2 == 0) && ((32-ret)%2 != 0))//“1”的个数是偶数，“0”的个数不是偶数
//            printf("1 ");
//        else if((ret%2 == 0) && ((32-ret)%2 == 0))//“1”的个数是偶数，“0”的个数不是偶数
//            printf("10 ");
//        else if((ret%2 != 0) && ((32-ret)%2 == 0))//“1”的个数不是偶数，“0”的个数是偶数
//            printf("0 ");
//        else//"1"的个数非偶数，“0”的个数非偶数。
//            printf("100 ");
//    }
//    return 0;
//}




int main() {
    int n = 0;
    int m = 0;
    scanf("%d %d",&n,&m);
    char arr[n][m];
    int i = 0;
    int j = 0;
    for(i = 0;i < n;i++)
    {
        getchar();//清除上一行输入的内存中的空格
        for(j = 0;j < m;j++)
        {
            scanf("%c",&arr[i][j]);
        }
    }
//    for(i = 0;i < n;i++)
//    {
//        for(j = 0;j < m;j++)
//        {
//            printf("%c ",arr[i][j]);
//        }
//        printf("\n");
//    }
    //根据每一个元素，进行判断。
    char arr_1[n+2][m+2];//比它多一位判断，减少数据溢出的烦恼.
    for(i = 0;i < n+2;i++)//先初始化为全无雷，然后把雷盘赋给显示盘。
    {
        for(j = 0;j < m+2;j++)
        {
            arr_1[i][j] = '0';//先初始化全部为‘0’，然后用Ascll码表值相加
        }
    }
    int x = 0;
    int y = 0;
    for(i = 1;i < n+1;i++)
    {
        for(j = 1;j < m+1;j++)
        {
            arr_1[i][j] = arr[x][y++];
            if(arr_1[i][j] == '.')
                arr_1[i][j] = '0';
        }
        x++;
        y = 0;
    }
//    for(i = 0;i < n+2;i++)
//    {
//        for(j = 0;j < m+2;j++)
//        {
//            printf("%c ",arr_1[i][j]);
//        }
//        printf("\n");
//    }
    //已经赋给它之后就开始计算
    for(i = 1;i < n+1;i++)
    {
        for(j = 1;j < m+1;j++)
        {
            if(arr_1[i][j] != '*')//'*'格不用计算，仍然显示'*'.
            {
                int m = 0;
                int n = 0;
                char count = '0';//初始化为‘0’，便于计算
                for(m = -1;m <= 1;m++)
                {
                    for(n = -1;n <= 1;n++)
                    {
                        if(m == 0 && n == 0)//同时为0时为本体，不用计数
                            ;
                        else
                            if(arr_1[i+m][j+n] == '*')//记录周围有多少个‘*’；
                                count++;//Ascll值加1
                    }
                }
                arr_1[i][j] = count;
            }
        }
    }
    //打印（按要求打印）
    for(i = 1;i < n+1;i++)
    {
        for(j = 1;j < m+1;j++)
        {
            printf("%c",arr_1[i][j]);
        }
        printf("\n");
    }
    return 0;
}

